
#include <cconf.h>

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>

int Done = 0;

void handler(int signum)
{
	Done =1;
}

void config_changed_cb(cconf_t * c, char * path, void * arg)
{
	char * value = cconf_get_value_str(c, "%s", path);
	fprintf(stderr, "configuration value changed for %s\nnew value: %s\n", path, value);
}

static int
scandir_cb (const struct dirent *e)
{
	char * p;
	if ((p = strstr(e->d_name, ".so")) != NULL)
	{
		*p = 0; return 1;
	}
	else
		return 0;
}

static int _detector_name_validate(char ** out, char * value, void * arg)
{
	cconf_t * c = arg;
	struct dirent **entries;
	int N,n, err = 1;
	char * path = cconf_get_value_str(c, "%s", "bar_path");
    
    if (path == NULL)
    {
		asprintf(out, "no path specified for detectors!");
		return 1;
	}
    
	N = scandir (path, &entries, &scandir_cb, alphasort);
	
	if (N < 0)
	{
		asprintf(out, "no files present in bar_path \"%s\"", path);
		return 1;
	}
			
	for (n = 0; n < N; ++n)
	{
		if (!strcmp(entries[n]->d_name, value))
			err = 0;
		
		free(entries[n]);
	}
	
	free(entries);
	
	if (err)
		asprintf(out, "detector %s not found in %s", value, path);
	
	return err;
}



int main(int argc, char *argv[])
{
	signal(SIGINT, handler);
	char *dump;
    cconf_t * cfg = cconf_create("test", &config_changed_cb, NULL);
    
    if (NULL == cfg)
    {
        fprintf(stderr, "couldn't create configuration object.\n");
        exit(1);
    }
    
	cconf_add_entries(cfg, 
		"foo_bility", "3.0", "how foo-able we are", "", "double",
		"goo_bility", "4", "how goo-able we are", "", "int",
		"age", "50", "how old you are", "", "intrange", "0-100", 
		"delay", "5.0", "how long to wait", "", "doublerange", "0-10",
		"modem", "land", "list of modems", "*", "strlist", "land,cell,sat",
		"bar_path", "/tmp/bar", "where to look for bar", "", "str",
		NULL);
    
    cconf_add_entry_specifier(cfg, "delay", "pre", "0.3");
        
    cconf_add_entry_usr(
		cfg, "bar", NULL, "which bar plug-in to use", NULL, 
		&_detector_name_validate, cfg, "string, from contents of bar_path directory"
	);
    
    if (cconf_optparse(cfg, argc, argv))
	{
		cconf_free(cfg);
		exit(1);
	}
    
    if (cconf_check_errors(cfg))
    {
        dump = cconf_get_errors(cfg);
        fprintf(stderr, "%s\n", dump);
        free(dump);
    }
    
    while (!Done)
    {
		sleep(1);
	}
    
    dump = cconf_dump(cfg, "\n","=");
    fprintf(stdout, "%s\n", dump);
    free(dump);
    
    cconf_free(cfg);
    exit(0);
}
